﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using DA_OOMModel;
using System.Data;
using System.Reflection;
using DA_OOMDALFactory;
using DA_OOMModelIDAL;
using System.Collections;
using NHibernate.Mapping;
using NHibernate.Cfg;
using DA_OOMNHibernateDAL;

namespace DaCredito
{
    public partial class WebPageGridForm : WebPage
    {


        protected Type ioTipoEntidade;
        protected Type ioTipoPKEntidade;
        protected Type[] ioListaTipoEntidadeSecundaria;
        protected string[] isNomeAtributos;
        protected string isNomeAtributoOrdenacao;
        private Usuario ioUsuario;
        private GridView ioGridViewLista;
        protected object ioInstanciaEntidade;

        public GridView GridViewLista
        {
            get { return ioGridViewLista; }
            set { ioGridViewLista = value; }
        }

        public Type Entidade
        {
            get { return ioTipoEntidade; }
            set { ioTipoEntidade = value; }
        }

        protected override void PrePageLoad()
        {

            base.PrePageLoad();
        }
        /*
        protected void Page_Load(object sender, EventArgs e)
        {
        }*/
        protected override void OnLoad(EventArgs e)
        {
            base.OnLoad(e);
            //base.Page_Load(sender, e);

            // Recupera a referencia da Grid de Listagem
            ioGridViewLista = (GridView) this.EncontrarControle("GridViewLista");

            this.CarregaLista();

            string lsIDEntidade = Request.QueryString[ioTipoEntidade.Name]; ;

            // Se nao definiu ID, carrega a lista
            if (lsIDEntidade == null || lsIDEntidade.Trim() == "")
            {
                this.EncontrarControle("DivLista").Visible = true;
                this.EncontrarControle("DivCadastro").Visible = false;
            }
            // Se ID é para inserir um novo registro
            else if (lsIDEntidade == "Novo")
            {
                this.CriaLinkRetornar();
                this.EncontrarControle("DivLista").Visible = false;
                this.EncontrarControle("DivCadastro").Visible = true;
            }
            else
            {
                this.CriaLinkRetornar();
                this.EncontrarControle("DivLista").Visible = false;
                this.EncontrarControle("DivCadastro").Visible = true;

            
                // Por reflexao, recupera a instancia do objeto DAL da Entidade
                MethodInfo loMetodoCriacaoDALEntidade = typeof(ConcreteDALFactory).GetMethod("Create" + ioTipoEntidade.Name + "DAL");
                object loEntidadeDAL = loMetodoCriacaoDALEntidade.Invoke(new ConcreteDALFactory(), null);
                
                // Por reflexao, recupera o tipo da EntidadePK da Entidade
                Type loTypeEntidadePK = ioTipoEntidade.GetProperty(ioTipoEntidade.Name + "PK", BindingFlags.Public | BindingFlags.Instance).PropertyType;

                // Declara um array com este tipo
                Type[] loTypesEntidadePK = new Type[1] { loTypeEntidadePK };

                // Por reflexao, recupera o metodo Load da Entidade
                MethodInfo loMetodoLoadEntidade = loEntidadeDAL.GetType().GetMethod("Load", loTypesEntidadePK);
                                
                // Cria um array e coloca o ID da Entidade
              //  object[] loParametrosConstrutorPK = new object[1] {Convert.ToInt32(lsTeste)};

               // object loObjetoEntidade = (IList) metodos3.Invoke(ioEntidadeDAL, );
                object loObjetoEntidadePK = Activator.CreateInstance(ioTipoPKEntidade, new object[1] { Convert.ToInt32(lsIDEntidade) });

                ioInstanciaEntidade = loMetodoLoadEntidade.Invoke(loEntidadeDAL, new object[1] { loObjetoEntidadePK });

               // Cliente loCliente = dal.Load(new ClientePK(Convert.ToInt32(lsTeste)));

                this.CarregaEntidadePagina(ioTipoEntidade, ioInstanciaEntidade);

                this.CarregaEntidadesPagina();
            }
        }
        protected virtual void CarregaEntidadesPagina()
        {

        }

       

        protected void CarregaLista()
        {
            Configuration cfg = new Configuration();
            cfg.Configure(Assembly.Load("DA_OOMNHibernateDAL"), "DA_OOMNHibernateDAL.hibernate.cfg.xml");
            
            PersistentClass classMapping = cfg.GetClassMapping(ioTipoEntidade);

            NHibernate.Mapping.Table physicalTable = classMapping.RootTable;

            // Cria um DataTable da tabela alvo da interface
            DataTable loDataTableEntidade = new DataTable(physicalTable.Name);

            List<string> loListaNomeColunas = this.GetListaNomesColunas(classMapping);
            // Adiciona um DataColumn para cada coluna definida
            foreach (string lsNomeColuna in loListaNomeColunas)
            {
                loDataTableEntidade.Columns.Add(lsNomeColuna);
            }

            // Por reflexao, recupera a instancia do objeto DAL da Entidade
            MethodInfo loMetodoCriacaoDALEntidade = typeof(ConcreteDALFactory).GetMethod("Create" + ioTipoEntidade.Name + "DAL");
            object ioEntidadeDAL = loMetodoCriacaoDALEntidade.Invoke(new ConcreteDALFactory(), null);

            // Por refelxao, recupera no banco todos os registros da Entidade
            IList loListaEntidade = this.GetListaEntidade(ioEntidadeDAL);

            string lsColunaOrdenacao = "";

            // Para cada registro, adiciona uma linha ao DataTable
            foreach (object loInstanciaEntidade in loListaEntidade)
            {

                DataRow loRow = loDataTableEntidade.NewRow();
                foreach (string lsNomeAtributo in isNomeAtributos)
                {
                    PropertyInfo loPropriedadeEntidade = ioTipoEntidade.GetProperty(lsNomeAtributo, BindingFlags.Public | BindingFlags.Instance);

                    //lsColunaOrdenacao = this.GetNomeColuna(classMapping, loPropriedadeEntidade.Name);

                    loRow.SetField(this.GetNomeColuna(classMapping, loPropriedadeEntidade.Name), loPropriedadeEntidade.GetValue(loInstanciaEntidade, null));
                    //loRow.SetField(lsColunaOrdenacao, loPropriedade2Entidade.GetValue(loInstanciaEntidade, null));


                }
                loDataTableEntidade.Rows.Add(loRow);
            }

            // Ordenação alfabetica da grade
            DataView loDataView = loDataTableEntidade.DefaultView;
            loDataView.Sort = isNomeAtributoOrdenacao;
            loDataTableEntidade = loDataView.ToTable();

            // Adiciona o DataTable a um DataSet
            DataSet loDataSetEntidade = new DataSet();
            loDataSetEntidade.Tables.Add(loDataTableEntidade);
            
            // Atribui o datasource e exibe os dados
            ioGridViewLista.DataSource = loDataSetEntidade;
            ioGridViewLista.DataBind();

            this.CriaLinkInsercaoNovo();
            
        }

        protected virtual IList GetListaEntidade(object aoEntidadeDAL)
        {
            // Por refelxao, recupera no banco todos os registros da Entidade
            MethodInfo loMetodoRecuperacaoListaEntidade = aoEntidadeDAL.GetType().GetMethod("Get" + ioTipoEntidade.Name + "List", Type.EmptyTypes);
            return (IList)loMetodoRecuperacaoListaEntidade.Invoke(aoEntidadeDAL, null);

        }
        protected void CriaLinkInsercaoNovo()
        {
            HyperLink loHyperLink = new HyperLink();
            loHyperLink.NavigateUrl = this.Request.FilePath + "?" + ioTipoEntidade.Name + "=Novo";
            loHyperLink.Text = "Inserir novo";
            ioGridViewLista.Parent.Controls.Add(loHyperLink);
        }
        protected void CriaLinkRetornar()
        {
            HyperLink loHyperLinkSuperior = new HyperLink();
            loHyperLinkSuperior.NavigateUrl = this.Request.FilePath;
            loHyperLinkSuperior.Text = "Retornar";
            this.EncontrarControle("DivCadastro").Parent.Controls.AddAt(0, loHyperLinkSuperior);

            HyperLink loHyperLinkInferior = new HyperLink();
            loHyperLinkInferior.NavigateUrl = this.Request.FilePath;
            loHyperLinkInferior.Text = "Retornar";
            this.EncontrarControle("DivCadastro").Parent.Controls.Add(loHyperLinkInferior);
        }
        protected override bool OnUpdate()
        {
            return true;

        }
    
        

    }
}
